--
-- @Author:      name
-- @DateTime:    2018-03-30 23:05:48
-- @Description: 桌子请求处理

local skynet = require "skynet"
-- local msgpack = require "msgpack_helper"
local NodeMessage = require "NodeMessage"
local config = require "configquery"
local json = require "cjson"
local AssertEx = AssertEx
local Table = class("Table")
local log = require "Log"
---------------------------------------------------------
-- Private
---------------------------------------------------------
function Table:ctor(message,userObj)
	self.userObj = userObj
	self.nodename = skynet.getenv("svr_id") --进程名
	self.nodeMessage = NodeMessage.new()
	self.msg = message
	

	self:register()

	-- print("____config___",config.pdk_room_set)
end

function Table:register()
	local msg = self.msg
	msg:registerSelf("enter_table_req",handler(self,self.enterTable))
	msg:registerSelf("leave_table_req",handler(self,self.leaveTable))
	msg:registerSelf("sitdown_req",handler(self,self.sitdown))
	msg:registerSelf("standup_req",handler(self,self.standup))
	msg:registerSelf("changetable_req",handler(self,self.changeTable))
	msg:registerSelf("room_state_req",handler(self,self.getRoomState))
	-- msg:registerSelf("enterprivate_req",handler(self,self.enterPrivateTable))
	msg:registerSelf("createtable_req",handler(self,self.createPrivate))
	msg:registerSelf("closeprivate_req",handler(self,self.closePrivate))
	msg:registerSelf("chat_req",handler(self,self.chat))

	msg:registerSelf("enterprivate_room_req",handler(self,self.enterPrivateRoom))
end

--需要添加一个玩家掉线延迟的功能
function Table:disconnect( playerid, tableid )	
	-- print("######logOut playerid:"..playerid.."table:"..tableid)
	if not tableid or tableid == 0 then --不在房间中
		return 
	end	
	local result = self.nodeMessage:callTable(tableid, 'lost_connect', playerid, {playerid})
	print("############result Table:disconnect#########",tableid,result,playerid)
	if result then
		self.userObj:updateTableid( playerid, 0)	
	end
	return result
end

function Table:createPlayer(user)
	--把当前进程各转到游戏中去
	local player = {}
	local usergame = user.user_info
	local userinfo = user.userInfoEx

	player.nodename = self.nodename
	player.nick = userinfo.uname
	player.icon = userinfo.uface	
	player.viplevel = usergame.uvip	
	player.chip = usergame.uchip
	player.diamond = usergame.udiamond
	player.level = usergame.ulevel
	player.playerid = usergame.uid
	player.pfid = userinfo.pfid	--php统计用 平台id
	player.usid = userinfo.usid	--php统计用 子平台id
	player.game = userinfo.game --php统计用
	player.channelid = userinfo.channelid
	player.fanka = usergame.room_ticket
	player.sex = userinfo.usex
	player.uwincnt = usergame.uwincnt --赢牌次数
	player.ulosecnt = usergame.ulosecnt --输牌次数
	player.udrawcnt = usergame.udrawcnt --和局次数
	player.win_streak = usergame.win_streak --最大连续胜局次数
	player.ip = user.u_info.addr --ip地址
	if player.playerid < 5000000 then 	
		player.robot = true
	end
	return player
end

--进入桌子
function Table:enterTable(user, args)
	-- print("______enterTable___user____",user,args)
	local tableid = args.tableid --or 10020
	local room_type = args.room_type
	AssertEx(tableid or room_type, 'enter_table_res', 1, 'tableid or roome_type 为空！')
	if user.tableid and user.tableid > 0 then--已经进入过房间
		--AssertEx(tableid == user.tableid, 'enter_table_res', 1, '已经进入过房间'..user.tableid.. '--'..(tableid or "nil"))
		tableid = user.tableid
		print("___________已经进入过房间___"..tableid)
	end	
	local userInfo = user.user_info
	local player = self:createPlayer(user)
	local playerid = player.playerid
	local result
	local tbState 
	if tableid then
		--参数错误
		AssertEx(tableid > 0, 'enter_table_res', 13)
	else		
		--通过场次取能进的桌子id
		tbState = self.nodeMessage:callGlobalService('tablestate', 'enter_table_req', user.playerid,room_type,tableid,player.chip)
		tableid = tbState[1]
		result = tbState[2]		
	end
	if tableid == -1 then 
		--进入场次错误
		AssertEx(false, 'enter_table_res', 19)
	elseif tableid == -2 then 
		--桌子已满
		AssertEx(false, 'enter_table_res', 20)
	elseif tableid == -3 then 
		--金币不足
		AssertEx(false, 'enter_table_res', 12)					
	end
	
	--print("_____enter___tableid___",tableid)
	--进入房间
 	result = self.nodeMessage:callTable(tableid, 'enter_table_req', player.playerid, player)
 	print("____enter_table_req__result___",result)
	if result and result.enter_table_res and not result.enter_table_res.err_no then
		self.userObj:updateTableid( playerid, tableid)		
	elseif result and result.enter_table_res and result.enter_table_res.err_no then
		return result
	end
	--游戏正在维护！
	AssertEx(result, 'enter_table_res', 7)
	return result
end

--离开桌子 
function Table:leaveTable( user, args  )
	local tableid = args.tableid
	local playerid = user.playerid
	--错误参数
	AssertEx(tableid, 'leave_table_res', 13)
	--未进入桌子
	AssertEx(user.tableid == tableid, 'leave_table_res', 10)

	local result = self.nodeMessage:callTable(tableid, 'leave_table_req', user.playerid, args)
	--"离开房间错误"
	AssertEx(result,'leave_table_res',10)
	--对游戏房间返回的错误信息进行判断
	if result and result.leave_table_res and result.leave_table_res.err_no then
		AssertEx(false,'leave_table_res',result.leave_table_res.err_no,result.leave_table_res.err_msg)
	end
	if result and result.leave_table_res and not result.leave_table_res.err_no then
		--更新玩家所在桌子
		self.userObj:updateTableid( playerid, 0)
	end
	return result
end

-- 换桌
function Table:changeTable(user,args)
	--[[
		1.先把人从原来桌子离开
		2.查找可用桌子，但摒掉之前的桌子
	--]]
	local tableid = args.tableid
	--更换房间失败
	local errorRes = {changetable_res = GetErrorTable(21)}	

	if not tableid or tableid ~= user.tableid then 
		print("__error_______没有进入房间 却请求换桌_______________")
		return 
	end
	local res = self.nodeMessage:callTable(user.tableid,'leave_table_req',user.playerid)
	if not res or (res.leave_table_res and res.leave_table_res.err_no )then 
		--离开桌子失败了
		return res
	end	
	local player = self:createPlayer(user)
	local playerid = player.playerid
	local tableid = user.tableid
	local result

	res = self.nodeMessage:callGlobalService('tablestate','changetable_req', playerid,tableid,player.chip)
	if not res then 
		return errorRes
	end
	tableid = res
	--房间已满
	AssertEx(tableid>0, 'changetable_res', 20)		
	--进入房间
	res = self.nodeMessage:callTable(tableid,'enter_table_req',playerid, player)
	if res and res.enter_table_res and not res.enter_table_res.err_no then
		self.userObj:updateTableid( playerid, tableid)		
		return {changetable_res={tableid=tableid}}
	end	

	return errorRes	
end

--场次相关
function Table:getRoomState(user,args)
	local tbRes = self.nodeMessage:callGlobalService('tablestate','player_num_req',user.playerid, args.gameid)
	--取场次数据错误
	AssertEx( next(tbRes), 'room_state_res',22)
	local tbState = {}
	for k,v in pairs(tbRes) do 
		local tb = {}
		tb.roomid = k 
		tb.player_num = v
		table.insert(tbState,tb)
	end
	local state = {
		room_state_res = {
			room_state = tbState
		}
	}
	return state
end

--坐下
function Table:sitdown(user, args)
	local tableid = args.tableid
	local seatid = args.seatid
	if not tableid or tableid ~= user.tableid then 
		print("__error_______没有进入房间 却请求坐下_______________")
		AssertEx(false , 'sitdown_res', 10)
	end	
	local res = self.nodeMessage:callTable(user.tableid,'sitdown_req',user.playerid,seatid)
	-- print("________res__",res)
	AssertEx(res , 'sitdown_res', 27)
	return res
end

--站起
function Table:standup(user, args)
	local tableid = args.tableid
	if not tableid or tableid ~= user.tableid then 
		print("__error_______没有进入房间 却请求坐下_______________", tableid , user)
		return 
	end		
	local res = self.nodeMessage:callTable(user.tableid,'standup_req',user.playerid)
	AssertEx(res , 'standup_res', 28)
	return res	
end

--聊天
function Table:chat(user,args)
	local chatType = args.chat_type
	-- local content = args.content
	local player = self:createPlayer(user)
	if chatType == 1 or chatType == 2 then 
		--桌子内消息
		AssertEx(user.tableid>0 , 'chat_res', 10)		
		local res = self.nodeMessage:callTable(user.tableid,'chat_req',user.playerid,args)		
	end

	return {chat_res={succese=true}}
end



function Table:enterPrivate(user,args,data,gameid)
	local userInfo = user.user_info
	local tableNum = args.tablenum or 0
	local gameid = gameid
	local tableid = getTableidByNum(gameid,tableNum)

	local player = self:createPlayer(user)
	local playerid = player.playerid
	local result	
	AssertEx(tableid , 'enterprivate_room_res', 1, 'tableid 为空！')
	if user.tableid and user.tableid > 0 then --已经进入房间,拉回玩家		
		tableid = user.tableid
	end	
	
 	result = self.nodeMessage:callTable(tableid, 'enter_table_req', player.playerid, player, 1)

	if result and result.enter_table_res and not result.enter_table_res.err_no then
		self.userObj:updateTableid( playerid, tableid)	
		--进入房间后扣卡

	elseif result and result.enter_table_res and result.enter_table_res.err_no then
		AssertEx(false, 'enterprivate_room_res', result.enter_table_res.err_no)
	end
	--游戏正在维护！
	AssertEx(result, 'enterprivate_room_res', 7)
	local res = {
		enterprivate_room_res=result.enter_table_res,
	}
	return res	
end


function Table:get_price(server_config,setting)
	for k,v in pairs(server_config.price) do
		if v.play_count == setting.play_count then
			return v.cost
		end
	end
end

function Table:enterPrivateRoom(user,args)
	local userInfo = user.user_info
	local playerid = user.playerid
	local gameid = args.gameid
	local table_num = args.tablenum
	local tableid = getTableidByNum(gameid,table_num)
	local roomid = 0
	AssertEx( (gameid and table_num), 'enterprivate_room_res', 13)--参数错误
	local sql = string.format('select * from private_tables where number=%d and gameid=%d',table_num,gameid)
	local data = self.nodeMessage:callService('mysql_service','execute',sql)
	if next(data) then
		data = data[1]	
	end	
	AssertEx(next(data), 'enterprivate_room_res', 42)--房间不存在

	roomid = getRoomType(tableid)
	local sql1 = 'select * from common_room where sub_id='..roomid
	local common_room = self.nodeMessage:callService('mysql_service','execute',sql1)

	if next(data) then
		common_room = common_room[1]	
	end	
	
	AssertEx(next(common_room), 'enterprivate_room_res', 13)--房间配置不存在
	--检查对应参数
	local setting = json.decode(data.setting)
	local player_num = setting.player_num or 4
	if setting and not setting.payer then
		setting.payer = 1
	end
	local server_config = json.decode(common_room.server_config)
	local managerid = data.managerid
	local fangkaCost = self:get_price(server_config,setting)
	if not setting or not fangkaCost then 
		print("__server_config__",server_config)
		print("__setting",setting)
		log.debug("enterprivate_room_res",setting,fangkaCost)
		AssertEx(false, 'enterprivate_room_res', 13)--参数错误
	end	

	if setting.payer == 1 and playerid == managerid then
		if userInfo.room_ticket < fangkaCost then 
			--房卡数不够
			log.debug("___1房卡不够___",userInfo.room_ticket,player_num)
			AssertEx(false, 'enterprivate_room_res', 45)

		else	

		end
	elseif setting.payer == 2 then
		fangkaCost = fangkaCost / player_num
		if userInfo.room_ticket  < fangkaCost then 
			--房卡数不够
			log.debug("___2房卡不够___",userInfo.room_ticket,player_num)
			AssertEx(false, 'enterprivate_room_res', 45)
		end		
	elseif setting.payer > 2 or setting.payer < 1 then
		AssertEx( false, 'enterprivate_room_res', 13)--参数错误
	end	
	
	--房主扣卡
	if playerid == managerid then
		local hUser = g_objects:getOne('User')
		local ok = hUser:changeFangka(playerid, -fangkaCost, 1)
		-- print("____4 ok___",ok,res)
		if ok then 
			--TODO 更新房间状态
			local sql = string.format("update private_tables set tableid = %d ,status=1 where number = %d and gameid=%d",tableid,table_num,gameid)
			self.nodeMessage:callService("mysql_service", "execute", sql)	
			
			return self:enterPrivate(user,args,data,gameid)
		else
			--扣钱失败
			self.nodeMessage:callGlobalService('tablestate','close_private',playerid, {tableid=tableid})
			AssertEx(result, 'enterprivate_room_res', 25)
		end
	else
		return self:enterPrivate(user,args,data,gameid)
	end
end


--创建私人桌(跑得快用于判断是否已创建房间)
function Table:createPrivate(user,args)
	local userInfo = user.user_info
	local playerid = user.playerid

	--是否已创建过房间
	local sql = string.format('select * from private_tables where managerid=%d and status>%d',playerid,0)
	local data = self.nodeMessage:callService('mysql_service','execute',sql)
	if next(data) and next(data[1]) then
		data = data[1]
		return {createtable_res={
			tableid = data.tableid,
			tablenum = data.number,
		}}		
	end	
	if not args.setting or args.setting=='' or not args.gameid then 
		AssertEx(false, 'createtable_res', 13)--参数错误
	end

end

function Table:closePrivate(user,args)

	local tableNum = args.table_num
	local gameid = args.gameid
	if args.gameid > 10 then
		gameid = args.gameid
	end
	local tableid = getTableidByNum(gameid,tableNum)
	print("____getTableidByNum__",tableNum,tableid)
	local player = self:createPlayer(user)
	local playerid = player.playerid
	local result	
	AssertEx(tableid , 'closeprivate_res', 1, 'tableid 为空！')
	
	--桌子是否存在
	--print("closePrivate",tableNum,tableid)
	local data = self.nodeMessage:callService('dbmgr_service','get_private_tables',tableid)
	--print("closePrivate",data)
	if not data or not next(data) then
		AssertEx(result, 'closeprivate_res', 42)
	end
	--进入房间
 	result = self.nodeMessage:callTable(tableid, 'closeprivate_req', player.playerid)
 	--print("____closePrivateTable___",tableid,result)	

	-- local res = self.nodeMessage:callGlobalService('tablestate','close_private',playerid, args)
	-- if not res then 
	-- 	--关闭错误
	-- 	AssertEx(result, 'closeprivate_res', 26)
	-- end
	return {
		closeprivate_res = {
			succese=result
		}
	}	
end

return Table